The process of rendering two-dimensional images from three-dimensional scenes is commonly referred to as image processing. As the modern computer industry evolves image processing evolves as well. One particular goal in the evolution of image processing is to make two-dimensional simulations or renditions of three-dimensional scenes as realistic as possible. One limitation of rendering realistic images is that modern monitors display images through the use of pixels.
A pixel is the smallest area of space which can be illuminated on a monitor. Most modern computer monitors will use a combination of hundreds of thousands or millions of pixels to compose the entire display or rendered scene. The individual pixels are arranged in a grid pattern and collectively cover the entire viewing area of the monitor. Each individual pixel may be illuminated to render a final picture for viewing.
One technique for rendering a real world three-dimensional scene onto a two-dimensional monitor using pixels is called rasterization. Rasterization is the process of taking a two-dimensional image represented in vector format (mathematical representations of geometric objects within a scene) and converting the image into individual pixels for display on the monitor. Rasterization is effective at rendering graphics quickly and using relatively low amounts of computational power; however, rasterization suffers from several drawbacks. For example, rasterization often suffers from a lack of realism because it is not based on the physical properties of light, rather rasterization is based on the shape of three-dimensional geometric objects in a scene projected onto a two dimensional plane. Furthermore, the computational power required to render a scene with rasterization scales directly with an increase in the complexity of the scene to be rendered. As image processing becomes more realistic, rendered scenes also become more complex. Therefore, rasterization suffers as image processing evolves, because rasterization scales directly with complexity.
Several alternative techniques rendering a real world three-dimensional scene onto a two-dimensional monitor using pixels have been developed based upon more realistic physical modeling. One such physical rendering technique is called ray tracing. The ray tracing technique traces the propagation of imaginary rays, rays which behave similar to rays of light, into a three-dimensional scene which is to be rendered onto a computer screen. The rays originate from the eye(s) of a viewer sitting behind the computer screen and traverse through pixels, which make up the computer screen, towards the three-dimensional scene. Each traced ray proceeds into the scene and may intersect with objects within the scene. If a ray intersects an object within the scene, properties of the object and several other contributing factors are used to calculate the amount of color and light, or lack thereof, the ray is exposed to. These calculations are then used to determine the final color of the pixel through which the traced ray passed.
The process of tracing rays is carried out many times for a single scene. For example, a single ray may be traced for each pixel in the display. Once a sufficient number of rays have been traced to determine the color of all of the pixels which make up the two-dimensional display of the computer screen, the two dimensional synthesis of the three-dimensional scene can be displayed on the computer screen to the viewer.
Ray tracing typically renders real world three-dimensional scenes with more realism than rasterization. This is partially due to the fact that ray tracing simulates how light travels and behaves in a real world environment, rather than simply projecting a three-dimensional shape onto a two dimensional plane as is done with rasterization. Therefore, graphics rendered using ray tracing more accurately depict on a monitor what our eyes are accustomed to seeing in the real world.
Furthermore, ray tracing also handles increases in scene complexity better than rasterization as scenes become more complex. Ray tracing scales logarithmically with scene complexity. This is due to the fact that the same number of rays may be cast into a scene, even if the scene becomes more complex. Therefore, ray tracing does not suffer in terms of computational power requirements as scenes become more complex as rasterization does.
One major drawback of ray tracing, however, is the large number of calculations, and thus processing power, required to render scenes. This leads to problems when fast rendering is needed. For example, when an image processing system is to render graphics for animation purposes such as in a game console. Due to the increased computational requirements for ray tracing it is difficult to render animation quickly enough to seem realistic (realistic animation is approximately twenty to twenty-four frames per second).
With continued improvements in semiconductor technology in terms of clock speed and increased use of parallelism; however, rasterization becomes viable for more complex images, and real time rendering of scenes using physical rendering techniques such as ray tracing becomes a more practical alternative to rasterization. At the chip level, multiple processor cores are often disposed on the same chip, functioning in much the same manner as separate processor chips, or to some extent, as completely separate computers. In addition, even within cores, parallelism is employed through the use of multiple execution units that are specialized to handle certain types of operations. Hardware-based pipelining is also employed in many instances so that certain operations that may take multiple clock cycles to perform are broken up into stages, enabling other operations to be started prior to completion of earlier operations. Multithreading is also employed to enable multiple instruction streams to be processed in parallel, enabling more overall work to performed in any given clock cycle.
Irrespective of whether raster-based or physical rendering is performed to render image data for a scene, the increased use of parallelism presents some challenges with respect to maintaining a coherent state in a parallelized, multithreaded architecture. As an example, conventional graphics software Application Programming Interfaces (API's), which are the libraries of routines that are called by application programs to control the rendering process (e.g., OpenGL™ and DirectX™), are not specifically designed to manage state data in a multithreaded environment. Single threaded graphics code (from the perspective of an application program) assumes a single coherent state for each operation, and as such, conventional graphics software API's typically expect function call execution to remain in order, which in turn requires intermixed state variables function calls and drawing function calls to remain in order.
As an example, a single threaded application program might make the following function calls when drawing a primitive:
glBegin(GL_TRIANGLES);  glColor(0,255,0,255); // set color to green  glVertex3f(100.0f, 100.0f, 0.0f);  glColor(0,0,255,255); // set color to blue  glVertex3f(150.0f, 100.0f, 0.0f);  glColor(255,0,0,255); // set color to red  Vertex3f(125.0f, 50.0f, 0.0f);glEnd( );
In this code, each vertex of a triangle, which is defined by the glVertex3f( ) function call, is set to a different color by virtue of the preceding glColor( ) function call. The first vertex is thus set to green, the second vertex is set to blue, and the third vertex is set to red.
In a single-threaded hardware environment, processing of the aforementioned code is presents no coherency problems, as the first vertex will be defined after the color is set to green, and the second vertex will be defined after the color has been changed to blue, as a result of the preceding glColor( ) function call. The change in state, from a vertex color of green to a vertex color of blue, is ensured as a result of the serial processing of the function calls in the code.
In a multithreaded hardware environment, however, it may be desirable to enable different function calls to be handled in parallel hardware threads to increase overall throughput, desirably without requiring any specific thread management from an application program. Based on thread workload, however, the order in which certain function calls are completed in different threads may not be guaranteed, resulting in potential coherency issues.
As a consequence, in the aforementioned code, the use of parallelization may provide the opportunity to define each vertex for the primitive in separate threads, thus shortening the time required to define the primitive. The vertex color, however, represents a shared state or context, since setting the color with a glColor( ) function call sets the color used for all subsequent function calls until the color is changed by another glColor( ) function call. Steps therefore must be taken to ensure, for example, that the vertex color applied to each vertex is correct according to the function calls issued by the application program. Otherwise, as an example, the second glColor( ) function call that changes the vertex color from green to blue could potentially change the vertex color before the first vertex is defined by the first glVertex( ) function call, resulting in the first vertex being set to the wrong color.
While synchronization may be used to serialize operations to maintain coherent state, doing so limits the potential performance gains that could otherwise be obtained as a result of parallelization, particularly if a certain thread is required to wait for other threads to reach certain points before that thread is able to proceed. A need therefore exists in the art for an improved manner of maintaining coherent state data in a multithreaded graphics processing architecture.